<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS网页布局</title>
  <link rel="stylesheet" href="https://unpkg.lejian.com/reveal.js@5.0.4/dist/reset.css">
  <link rel="stylesheet" href="https://unpkg.lejian.com/reveal.js@5.0.4/dist/reveal.css">
  <link rel="stylesheet" href="https://unpkg.lejian.com/reveal.js@5.0.4/dist/theme/moon.css">
  <link rel="stylesheet" href="https://unpkg.lejian.com/reveal.js@5.0.4/plugin/highlight/monokai.css">
  <style>
    .code-wrapper .hljs {
      font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
      line-height: 1.8;
      border-radius: 8px;
    }

    .hljs::-webkit-scrollbar-track {
      background-color: transparent;
    }

    .hljs::-webkit-scrollbar {
      height: 6px;
      width: 6px;
      background-color: transparent;
    }

    .hljs::-webkit-scrollbar-thumb {
      background-color: #0b4865;
      border-radius: 4px;
    }
  </style>
</head>

<body>

  <div class="reveal">
    <div class="slides">
      <section data-auto-animate data-auto-animate-unmatched="fade" data-background="/layout.png">
      </section>

      <section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$"
        data-background-image="https://www.svgshapes.in/assets/Maika-0b8f6f5b.svg">
        <script type="text/template">
## 核心内容

1. Flex 布局
2. Grid 布局

---


## Flex 弹性盒布局

Flexbox 布局也叫 Flex 布局，弹性盒子布局


---


## 主轴与交叉轴 ​

- `main axis`: 主轴
- `cross axis`: 交叉轴，与主轴垂直

--

![](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox/flex_terms.png)

---

## 父容器

```
- `flex-direction` 主轴方向 row | column （默认 row）
- `flex-wrap` 是否换行 nowrap | wrap (默认 nowrap)
- `flex-flow` 是 flex-direction 属性和 flex-wrap 属性的简写 flex-flow: row/wrap
- `justify-content` 主轴对齐方式
- `align-items` 交叉轴对齐方式
- `align-content` 多轴对齐（flex: wrap 时有效）
```

--

```css
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
align-items: flex-start | flex-end | center | baseline | stretch;
align-content: flex-start | flex-end | center | space-between | space-around |
stretch;
}
```

---

### 对齐方式

```markdown
- `flex-start` 对齐到起点
- `flex-end` 对齐到终点
- `center` 居中对齐
- `space-between` 两端对齐
- `space-around` 平分空间
- `baseline` 以文本基线对齐
- `stretch` 拉伸对齐
```
        </script>
      </section>

      <section data-background-image="https://www.svgshapes.in/assets/Maika-0b8f6f5b.svg">
        <section data-auto-animate style="height: 600px">
          <p style="opacity: 0.3; font-size: 18px;">justify-content</p>
          <p style="margin-top: 260px;">flex-start</p>
          <div data-id="1"
            style="background: rgb(58 174 89); position: absolute; top: 150px; left: 24%; width: 500px; height: 100px; border-radius: 8px;">
          </div>
          <div data-id="2"
            style="background: white; position: absolute; top: 170px; left: 26%; width: 60px; height: 60px; border-radius: 4px;">
          </div>
          <div data-id="3"
            style="background: white; position: absolute; top: 170px; left: 34%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
          <div data-id="4"
            style="background: white; position: absolute; top: 170px; left: 42%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
        </section>
        <section data-auto-animate style="height: 600px">
          <p style="opacity: 0.3; font-size: 18px;">justify-content</p>
          <p style="margin-top: 260px;">flex-end</p>
          <div data-id="1"
            style="background: rgb(58 174 89); position: absolute; top: 150px; left: 24%; width: 500px; height: 100px; border-radius: 8px;">
          </div>
          <div data-id="2"
            style="background: white; position: absolute; top: 170px; left: 52%; width: 60px; height: 60px; border-radius: 4px;">
          </div>
          <div data-id="3"
            style="background: white; position: absolute; top: 170px; left: 60%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
          <div data-id="4"
            style="background: white; position: absolute; top: 170px; left: 68%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
        </section>
        <section data-auto-animate style="height: 600px">
          <p style="opacity: 0.3; font-size: 18px;">justify-content</p>
          <p style="margin-top: 260px;">center</p>
          <div data-id="1"
            style="background: rgb(58 174 89); position: absolute; top: 150px; left: 24%; width: 500px; height: 100px; border-radius: 8px;">
          </div>
          <div data-id="2"
            style="background: white; position: absolute; top: 170px; left: 39%; width: 60px; height: 60px; border-radius: 4px;">
          </div>
          <div data-id="3"
            style="background: white; position: absolute; top: 170px; left: 47%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
          <div data-id="4"
            style="background: white; position: absolute; top: 170px; left: 55%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
        </section>
        <section data-auto-animate style="height: 600px">
          <p style="opacity: 0.3; font-size: 18px;">justify-content</p>
          <p style="margin-top: 260px;">space-between</p>
          <div data-id="1"
            style="background: rgb(58 174 89); position: absolute; top: 150px; left: 24%; width: 500px; height: 100px; border-radius: 8px;">
          </div>
          <div data-id="2"
            style="background: white; position: absolute; top: 170px; left: 26%; width: 60px; height: 60px; border-radius: 4px;">
          </div>
          <div data-id="3"
            style="background: white; position: absolute; top: 170px; left: 47%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
          <div data-id="4"
            style="background: white; position: absolute; top: 170px; left: 68%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
        </section>
        <section data-auto-animate style="height: 600px">
          <p style="opacity: 0.3; font-size: 18px;">justify-content</p>
          <p style="margin-top: 260px;">space-around</p>
          <div data-id="1"
            style="background: rgb(58 174 89); position: absolute; top: 150px; left: 24%; width: 500px; height: 100px; border-radius: 8px;">
          </div>
          <div data-id="2"
            style="background: white; position: absolute; top: 170px; left: 32%; width: 60px; height: 60px; border-radius: 4px;">
          </div>
          <div data-id="3"
            style="background: white; position: absolute; top: 170px; left: 47%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
          <div data-id="4"
            style="background: white; position: absolute; top: 170px; left: 61%; width: 60px; height: 60px;  border-radius: 4px;">
          </div>
        </section>
      </section>

      <section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$"
        data-background-image="https://www.svgshapes.in/assets/Maika-0b8f6f5b.svg">
        <script type="text/template">

## 子元素

```markdown
- `flex-grow` 放大比例 number 默认 0 存在剩余空间，也不放大
- `flex-shrink` 缩小比例 number 默认 1 剩余空间不足时，自动缩小
- `flex-basis` 原始大小（用于计算剩余空间）默认 auto
- `flex` 是 flex-grow, flex-shrink 和 flex-basis 的简写
- `align-self` 用于设置当前元素对齐方式
- `order` 排序值
```

--

<p style="opacity: 0.5; font-size: 18px;">flex: 1</p>

```css
.item {
  /* 自动放大、自动缩小 (剩余空间计算不考虑该元素大小)*/
  // flex: 1 1 0%;
  flex: 1;
}
```

--

<p style="opacity: 0.5; font-size: 18px;">flex: 0</p>

```css
.item {
  /* 不放大，会缩小 (剩余空间计算不考虑该元素大小)*/
  // flex: 0 1 0%;
  flex: 0;
}
```

--

<p style="opacity: 0.5; font-size: 18px;">flex: auto</p>

```css
.item {
  /* 会放大、会缩小  (剩余空间计算考虑该元素初始大小)*/
  // flex: 1 1 auto;
  flex: auto;
}
```

--

<p style="opacity: 0.5; font-size: 18px;">flex: none</p>

```css
.item {
  /* 不放大，不缩小 (剩余空间计算考虑该元素初始大小)*/
  // flex: 0 0 auto;
  flex: none;
}
```

--

<p style="opacity: 0.5; font-size: 18px;">flex: 100px</p>

```css
.item {
  /* 会放大、会缩小  (剩余空间计算考虑该元素初始大小)*/
  // flex: 1 1 100px;
  flex: 100px;
}
```

--

<p style="opacity: 0.5; font-size: 18px;">align-self 自身对齐</p>

```css
.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
```

---

## 文档参考

- [彻底理解 CSS Flexbox 布局](https://juejin.cn/post/7004622232378966046#heading-0)
- [Flex 布局教程：语法篇](https://ruanyifeng.com/blog/2015/07/flex-grammar.html)

--

## 视频教程

- [flex 弹性布局 动画详解系列](https://www.bilibili.com/video/BV1Rv4y177rj/?spm_id_from=333.337.search-card.all.click&vd_source=678264307a6e2703434ac8209b73fd74)
- [2 分钟掌握 CSS flexbox 布局](https://www.bilibili.com/video/BV1P7411m7Nu/?spm_id_from=333.788&vd_source=678264307a6e2703434ac8209b73fd74)

--

## 演练场

- [Flexbox Playground](https://flexbox.tech/)
- [the-echoplex](https://the-echoplex.net/flexyboxes/)
- [bradwoods](https://layout.bradwoods.io/)

</script>
      </section>

      <section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$"
        data-background-image="/grid-bg.png">
        <script type="text/template">


## Grid 网格布局

将网页划分成一个个网格

任意组合不同的网格可生成各种布局

---

## 与 Flex 的不同

- Flex 是轴线布局，一维布局
- Grid 是网格布局，二维布局

---

## 容器属性

```markdown
- `display: grid` 设置容器为网格
- `grid-template-rows` 行模板设置
- `grid-template-columns` 列模板设置
- `gap` 间距，两个值时，第 1 个是行间距，第 2 个是列间距，一个值时，表示行和列间距相同
- `grid-template-areas` 设置网格区域模板(为每个单元格命名)
- `grid-auto-flow` 设置子元素排列顺序，默认先行后列 row | column | row dense | column dense
- `grid-auto-rows` 当行不够时，设置新增行的行高
- `grid-auto-columns` 当列不够时，设置新增列的列宽
```

--

### 指定所有单元格的对齐方式

```markdown
- `justify-items` 设置单元格内容的水平对齐, 默认是 stretch
- `align-items` 设置单元格内容的垂直对齐, 默认是 stretch
- `place-items` 是 align-items 属性和 justify-items 属性的合并简写形式
```

```css
.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}
```
<!-- .element: class="fragment" data-fragment-index="1" -->

--

### 指定网格整体内容的对齐方式

<p style="font-size: 18px">前提是网格整个大小要小于容器大小（行和列设置具体值时）</p>

```markdown
- `justify-content` 整个内容区域在容器里面的水平对齐
- `align-content` 整个内容区域的垂直对齐
- `place-content` 是 align-content 属性和 justify-content 属性的合并简写形式
```

```css
.container {
  justify-content: start | end | center | stretch | space-around | space-between
    | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between |
    space-evenly;
}
```
<!-- .element: class="fragment" data-fragment-index="1" -->

---

## 项目属性（单元格）

--

### 指定单元格的网格线

```markdown
- `grid-column-start` 左边网格线编号
- `grid-column-end` 右边网络线编号
- `grid-row-start` 上边网格线编号
- `grid-row-end` 下边网格线编号
- `grid-column` grid-column-start 与 grid-column-end 的简写 1/3 等同于 1 / span 2
- `grid-row` grid-row-start 与 grid-row-end 的简写 1/3
- `grid-area` 可以指定区域名称,也可以用作 grid-row-start、grid-column-start、grid-row-end、grid-column-end 的合并简写形式
```

--

```css
.box6 .item1 {
  /* grid-column-start: 1;
    grid-column-end: 3; */
  grid-column: 1/3;
  /* grid-column: 1/span 2; */
}

.box6 .item2 {
  /* grid-row-start: 1;
    grid-row-end: 3; */
  grid-row: 1/3;
}

.box6 .item3 {
  /* 指定网络编号: 行始 / 列始 / 行终 / 列终 */
  grid-area: 2 / 1 / 4 / 3;
}

.box6 .item4 {
  /* 列方向 合并2个单元格 */
  grid-column: span 2;
}

.box6 .item7 {
  /* 行方向 合并3个单元格 */
  grid-row: span 3;
}
```

--


### 设置单元格内容对齐方式

```markdown
- `justify-self` 设置单元格内容的水平对齐
- `align-self` 设置单元格内容的垂直对齐
- `place-self` 是 align-self 属性和 justify-self 属性的合并简写形式, 默认都是 stretch
```

```css
.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}
```
<!-- .element: class="fragment" data-fragment-index="1" -->

---

## 文档参考

- [Grid MDN](https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Grids)
- [阮一峰 CSS Grid 网格布局教程](https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html)
- [grid 常用布局](https://gridbyexample.com/examples/)
- [利用 CSS 网格布局实现常用布局 MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_grid_layout/Realizing_common_layouts_using_grids)


--

## 视频教程

- [2 分钟掌握 CSS Grid 布局](https://www.bilibili.com/video/BV18p411A7JB/?spm_id_from=333.788&vd_source=678264307a6e2703434ac8209b73fd74)
- [CSS Grid 布局设置跨行、跨列和堆叠顺序](https://www.bilibili.com/video/BV1Xr4y127Jf/?spm_id_from=333.337.search-card.all.click&vd_source=678264307a6e2703434ac8209b73fd74)
- [grid 网格布局真香](https://www.bilibili.com/video/BV1gw41167gh/?spm_id_from=333.337.search-card.all.click&vd_source=678264307a6e2703434ac8209b73fd74)
- [六分钟让你了解 Grid 布局](https://www.bilibili.com/video/BV127411s7XN/?spm_id_from=333.337.search-card.all.click&vd_source=678264307a6e2703434ac8209b73fd74)
- [超简单并超详细的 CSS Grid 布局（上）](https://www.bilibili.com/video/BV1Q54y1272g/?spm_id_from=333.337.search-card.all.click&vd_source=678264307a6e2703434ac8209b73fd74)

--

## 演练场

- [bradwoods](https://layout.bradwoods.io/customize)


---

## Q&A

</script>
      </section>
    </div>
  </div>

  <script type="module">
    import Reveal from 'https://unpkg.lejian.com/reveal.js@5.0.4/dist/reveal.esm.js'
    import Markdown from 'https://unpkg.lejian.com/reveal.js@5.0.4/plugin/markdown/markdown.esm.js'
    import Highlight from 'https://unpkg.lejian.com/reveal.js@5.0.4/plugin/highlight/highlight.esm.js'
    Reveal.initialize({
      center: true,
      hash: true,
      progress: true,
      slideNumber: true,
      plugins: [Markdown, Highlight]
    });
  </script>
</body>

</html>